package com.electromagnetic.industry.software.manage.service.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.electromagnetic.industry.software.common.cons.ElectromagneticConstants;
import com.electromagnetic.industry.software.common.enums.DataOwnEnum;
import com.electromagnetic.industry.software.common.enums.EffectFlagEnum;
import com.electromagnetic.industry.software.common.enums.EleDataStatusEnum;
import com.electromagnetic.industry.software.common.enums.FilePermission;
import com.electromagnetic.industry.software.common.util.UserThreadLocal;
import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper;
import com.electromagnetic.industry.software.manage.mapper.UserRoleMapper;
import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo;
import com.electromagnetic.industry.software.manage.pojo.models.RolePermission;
import com.electromagnetic.industry.software.manage.pojo.models.UserRole;
import com.electromagnetic.industry.software.manage.service.PermissionService;
import com.electromagnetic.industry.software.manage.service.RolePermissionService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
public class PermissionServiceImpl implements PermissionService {

    @Resource
    UserRoleMapper userRoleMapper;
    @Resource
    RolePermissionService rolePermissionService;
    @Resource
    EdFileInfoMapper edFileInfoMapper;

    /**
     * 用户对个人数据拥有所有权限
     *
     * @return
     */
    @Override
    public Map<String, Boolean> getPersonalPermission() {
        return transToMap(FilePermission.getAllCodes(), true);
    }

    /**
     * 查询当前用户在当前目录的功能权限
     *
     * @param userId
     * @param id
     * @return
     */
    @Override
    @Transactional
    public Map<String, Boolean> getUserPermission(String userId, String id, Boolean includeView) {

        List<String> roleIds = getRoles(userId);
        // 只有当 roleIds 不为空且不为 null 时，才添加 in 条件
        if (roleIds.isEmpty()) {
            return new HashMap<>();
        }
        LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(RolePermission::getPermissionCode)
                .eq(RolePermission::getFileId, id)
                .eq(RolePermission::getEffectFlag, EffectFlagEnum.EFFECT.code)
                .in(RolePermission::getRoleId, roleIds);
        List<String> permissionCodes = rolePermissionService.listObjs(queryWrapper).stream().map(Object::toString).toList();
        Map<String, Boolean> res = transToMap(permissionCodes, includeView);
        UserThreadLocal.setSuccessInfo("", "", "查看当前目录功能权限成功");
        return res;

    }


    /**
     * 获取当前用户有权限访问的目录id
     *
     * @return
     */
    @Override
    public List<String> getAccessibleTree() {
        String userId = UserThreadLocal.getUserId();
        List<String> roleIds = getRoles(userId);

        if (CollUtil.isEmpty(roleIds)) {
            return new ArrayList<>();
        }
        LambdaQueryWrapper<RolePermission> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.select(RolePermission::getFileId)
                .in(RolePermission::getRoleId, roleIds)
                .eq(RolePermission::getEffectFlag, EffectFlagEnum.EFFECT.code)
                .eq(RolePermission::getPermissionCode, FilePermission.VIEW.getCode());
        List<String> ids = rolePermissionService.listObjs(queryWrapper1).stream().map(Object::toString).toList();
        if (CollUtil.isEmpty(ids)) {
            return new ArrayList<>();
        }
        Set<String> result = new HashSet<>();
        // 把父亲节点加上
        List<EdFileInfo> edFileInfos = edFileInfoMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class)
                .select(EdFileInfo::getFilePath)
                .in(EdFileInfo::getId, ids));
        for (EdFileInfo file : edFileInfos) {
            String[] parentIds = file.getFilePath().split(ElectromagneticConstants.MYSQL_FILE_PATH_SPLIT);
            result.addAll(Arrays.asList(parentIds));
        }
        return new ArrayList<>(result);
    }

    /**
     * 根据用户获得角色
     *
     * @param userId
     * @return
     */
    private List<String> getRoles(String userId) {
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(UserRole::getRoleId)
                .eq(UserRole::getUserId, userId)
                .eq(UserRole::getEffectFlag, EffectFlagEnum.EFFECT.code);
        return userRoleMapper.selectObjs(queryWrapper).stream().map(Object::toString).toList();
    }

    /**
     * 获得角色权限
     *
     * @param roleId
     * @param fileId
     * @return
     */
    @Override
    public List<String> getPermissionCodes(String roleId, String fileId) {
        LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(RolePermission::getPermissionCode)
                .eq(RolePermission::getFileId, fileId)
                .eq(RolePermission::getRoleId, roleId)
                .eq(RolePermission::getEffectFlag, EffectFlagEnum.EFFECT.code);
        return rolePermissionService.listObjs(queryWrapper).stream().map(Object::toString).toList();
    }

    /**
     * 用户权限列表 转换为 哈希
     *
     * @param permissionCodes
     * @return
     */
    @Override
    public Map<String, Boolean> transToMap(List<String> permissionCodes, Boolean includeView) {
        Map<String, Boolean> result = new HashMap<>();
        List<String> allCodes;
        if (includeView.equals(Boolean.TRUE)) {
            allCodes = FilePermission.getAllCodes();
        } else {
            allCodes = FilePermission.getAllCodesExcludeView();
        }
        for (String code : allCodes) {
            result.put(code, permissionCodes.contains(code));
        }
        return result;
    }

    /**
     * 过滤有导出权限的文件id
     *
     * @param ids
     */
    @Override
    public Map<String, Boolean> filterExportIds(String[] ids) {
        Map<String, Boolean> map = new HashMap<>();
        if (ids.length == 0) {
            return map;
        }

        String userId = UserThreadLocal.getUserId();
        List<String> roleIds = getRoles(userId);
        if (roleIds == null || roleIds.isEmpty()) {
            return map;
        }

        for (String id : ids) {
            LambdaQueryWrapper<RolePermission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RolePermission::getFileId, id)
                    .eq(RolePermission::getPermissionCode, FilePermission.EXPORT.getCode())
                    .eq(RolePermission::getEffectFlag, EffectFlagEnum.EFFECT.code)
                    .in(RolePermission::getRoleId, roleIds);
            long count = rolePermissionService.count(queryWrapper);
            map.put(id, count > 0);

            // 添加父节点
            if (count > 0) {
                EdFileInfo file = edFileInfoMapper.selectById(id);
                String[] parentIds = file.getFilePath().split("_");
                for (String parentId : parentIds) {
                    map.put(parentId, true);
                }
            }
        }
        return map;
    }


    /**
     * 同步权限
     */
    @Override
    public void syncPermissions(String prjId) {

        // 获取当前项目所有已逻辑删除的节点，失效其权限
        LambdaQueryWrapper<EdFileInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(EdFileInfo::getDataStatus, EleDataStatusEnum.WAIT_DELETED.code)
                .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
                .likeRight(EdFileInfo::getFilePath, prjId);
        List<String> disableIds = edFileInfoMapper.selectList(queryWrapper).stream().map(EdFileInfo::getId).toList();

        LambdaUpdateWrapper<RolePermission> updateWrapper = new LambdaUpdateWrapper<>();
        if (!disableIds.isEmpty()) {
            updateWrapper.set(RolePermission::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code)
                    .in(RolePermission::getFileId, disableIds);
            rolePermissionService.update(updateWrapper);
        }

        // 获取当前项目所有已发布的节点
        LambdaQueryWrapper<EdFileInfo> infoWrapper = new LambdaQueryWrapper<>();
        infoWrapper.likeRight(EdFileInfo::getFilePath, prjId)
                .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)
                .eq(EdFileInfo::getDataStatus, EleDataStatusEnum.PUBLISHED.code)
                .eq(EdFileInfo::getDataOwn, DataOwnEnum.SYS_PRJ.code);
        List<EdFileInfo> files = edFileInfoMapper.selectList(infoWrapper);

        // 同步权限
        rolePermissionService.syncPermissionsAfterTreeUpdate(files, prjId);
    }

    /**
     * 判断用户有无权限
     *
     * @param permissionCode 权限
     * @param userId         用户编码
     * @param fileId         文件编码
     * @return
     */
    @Override
    public boolean isPermitted(String permissionCode, String userId, String fileId) {
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId, userId)
                .eq(UserRole::getEffectFlag, EffectFlagEnum.EFFECT.code);
        List<String> roleIds = Optional.ofNullable(userRoleMapper.selectList(queryWrapper))
                .orElse(Collections.emptyList())
                .stream().map(UserRole::getRoleId).toList();

        if (roleIds.isEmpty()) {
            return false;
        }

        LambdaQueryWrapper<RolePermission> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(RolePermission::getPermissionCode, permissionCode)
                .eq(RolePermission::getFileId, fileId)
                .eq(RolePermission::getEffectFlag, EffectFlagEnum.EFFECT.code)
                .in(RolePermission::getRoleId, roleIds);
        return rolePermissionService.count(queryWrapper1) > 0;
    }
}
